/**
 * 
 */
package org.scohen.juploadr.prefs;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Version implements Comparable {
    private String additional;
    private boolean hasAdditional;
    private int additionalVersion;
    public int[] parts;
    private static Pattern p = Pattern.compile("[\\d\\.]+((\\w+)(\\d{1,}))$");
    private static List<String> rankings;

    static {
        rankings = new ArrayList<String>();
        rankings.add("alpha");
        rankings.add("beta");
        rankings.add("rc");
    }

    public Version(String vStr) {

        parse(vStr);
    }

    private void parse(String v) {
        Matcher m = p.matcher(v);
        if (m.matches()) {
            String which = m.group(2);
            additional = which;
            hasAdditional = true;
            additionalVersion = Integer.parseInt(m.group(3));
            v = v.substring(0, v.indexOf(m.group(1)));
        }
        String[] sParts = v.split("\\.");
        parts = new int[sParts.length];
        for (int i = 0; i < sParts.length; i++) {
            parts[i] = Integer.parseInt(sParts[i]);
        }
    }

    public int compareTo(Object o) {
        Version another = (Version) o;
        int cmp = 0;
        for (int i = 0; i < parts.length; i++) {
            if (i < another.parts.length) {
                if (parts[i] == another.parts[i]) {
                    continue;
                } else {
                    cmp = parts[i] - another.parts[i];
                    break;
                }
            } else {
                cmp = 1;
            }
        }
        if (cmp == 0) {
            if (another.parts.length > parts.length) {
                cmp = -1;
            }
            if (hasAdditional || another.hasAdditional()) {
                // handle beta versions
                cmp = compareSubVersions(this, another);
            }
        }
        return cmp;
    }

    private int compareSubVersions(Version version, Version another) {
        if (version.hasAdditional() && another.hasAdditional) {
            if (version.getAdditional().equalsIgnoreCase(another.getAdditional())) {
                return version.getAdditionalVersion() - another.getAdditionalVersion();
            } else {
                return rankings.indexOf(version.getAdditional()) - rankings.indexOf(another.getAdditional());
            }
        } else if (version.hasAdditional() && !another.hasAdditional()) {
            return -1;
        } else {
            return 1;
        }
    }

    public String getAdditional() {
        return additional;
    }

    public int getAdditionalVersion() {
        return additionalVersion;
    }

    public boolean hasAdditional() {
        return hasAdditional;
    }
}